package com.atguigu.srb.core.service.impl;

import com.atguigu.srb.common.util.JwtUtils;
import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.common.util.MD5;
import com.atguigu.srb.core.mapper.LendMapper;
import com.atguigu.srb.core.mapper.UserAccountMapper;
import com.atguigu.srb.core.mapper.UserLoginRecordMapper;
import com.atguigu.srb.core.pojo.entity.Lend;
import com.atguigu.srb.core.pojo.entity.UserAccount;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.mapper.UserInfoMapper;
import com.atguigu.srb.core.pojo.entity.UserLoginRecord;
import com.atguigu.srb.core.pojo.vo.LoginVO;
import com.atguigu.srb.core.pojo.vo.RegisterVo;
import com.atguigu.srb.core.pojo.vo.UserInfoQuery;
import com.atguigu.srb.core.pojo.vo.UserInfoVO;
import com.atguigu.srb.core.service.UserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.Year;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户基本信息 服务实现类
 * </p>
 *
 * @author lsyandwh
 * @since 2022-12-02
 */
@Transactional
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private UserLoginRecordMapper userLoginRecordMapper;

    private static final String NUMBER_CODE = "api.sms.phone.";

    @Override
    public void register(RegisterVo registerVo) {
        //判断当前用户是否存在
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile",registerVo.getMobile());
        Integer count = baseMapper.selectCount(wrapper);
        Assert.isTrue(count == 0, ResponseEnum.MOBILE_EXIST_ERROR);

        //判断验证码是否正确
        String code = (String) redisTemplate.opsForValue().get(NUMBER_CODE + registerVo.getMobile());
        System.out.println("code = " + code);
        System.out.println("registerVo.getCode() = " + registerVo.getCode());
        Assert.equals(code,registerVo.getCode(),ResponseEnum.CODE_ERROR);

        //转换数据
        UserInfo userInfo = new UserInfo();
        userInfo.setUserType(registerVo.getUserType());
        userInfo.setNickName(registerVo.getMobile());
        userInfo.setName(registerVo.getMobile());
        userInfo.setMobile(registerVo.getMobile());
        userInfo.setPassword(MD5.encrypt(registerVo.getPassword()));
        userInfo.setStatus(UserInfo.STATUS_NORMAL); //设置账户状态，默认正常
        //设置一张静态资源服务器上的头像图片
        userInfo.setHeadImg("https://srb-file-imgs.oss-cn-hangzhou.aliyuncs.com/72f298b9_E880884_d0f63115.png");
        baseMapper.insert(userInfo);

        //创建会员账户
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userInfo.getId());
        userAccountMapper.insert(userAccount);
    }

    @Override
    public UserInfoVO login(LoginVO loginVO, String ip) {

        Integer userType = loginVO.getUserType();
        String mobile = loginVO.getMobile();
        String password = loginVO.getPassword();

        //数据校验
        Assert.notNull(mobile,ResponseEnum.MOBILE_NULL_ERROR);
        Assert.notNull(password,ResponseEnum.PASSWORD_NULL_ERROR);

        //根据手机号与用户类型查询用户信息
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<UserInfo>()
                .eq("mobile",mobile)
                .eq("user_type",userType);
        UserInfo userInfo = baseMapper.selectOne(wrapper);

        //用户信息验证
        Assert.notNull(userInfo,ResponseEnum.LOGIN_MOBILE_ERROR);
        Assert.equals(MD5.encrypt(password),userInfo.getPassword(),ResponseEnum.LOGIN_PASSWORD_ERROR);
        Assert.equals(userInfo.getStatus(),UserInfo.STATUS_NORMAL,ResponseEnum.LOGIN_LOKED_ERROR);

        //记录登录日志
        UserLoginRecord userLoginRecord = new UserLoginRecord();
        userLoginRecord.setUserId(userInfo.getId());
        userLoginRecord.setIp(ip);
        userLoginRecordMapper.insert(userLoginRecord);

        //生成token
        String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setToken(token);
        userInfoVO.setName(userInfo.getName());
        userInfoVO.setNickName(userInfo.getNickName());
        userInfoVO.setHeadImg(userInfo.getHeadImg());
        userInfoVO.setMobile(userInfo.getMobile());
        userInfoVO.setUserType(userType);

        return userInfoVO;
    }

    @Override
    public IPage<UserInfo> pageList(Integer page, Integer limit, UserInfoQuery userInfoQuery) {

        //1.组装分页条件
        IPage<UserInfo> iPage = new Page<>();
        iPage.setCurrent(page);
        iPage.setSize(limit);

        //2.判断UserInfoQuery是否有数据，如果没有数据则查询全部
        if(userInfoQuery == null){
            return baseMapper.selectPage(iPage, null);
        }

        //3.组装查询条件
        Integer userType = userInfoQuery.getUserType();
        String mobile = userInfoQuery.getMobile();
        Integer status = userInfoQuery.getStatus();
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<UserInfo>()
                //如果条件不等于空则组装查询条件
                .eq(userType != null,"user_type",userType)
                .eq(mobile != null,"mobile",mobile)
                .eq(status != null,"status",status);

        return baseMapper.selectPage(iPage, wrapper);
    }

    @Override
    public void lock(Long id, Integer status) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setStatus(status);

        baseMapper.updateById(userInfo);
    }

    @Override
    public UserInfo initial(String userId) {

        //1.查询用户基本信息
        UserInfo userInfo = baseMapper.selectById(Long.parseLong(userId));

        Map<String ,Object> map = new HashMap<>();

        //2.查询用户最近登入记录
        QueryWrapper<UserLoginRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId)
                        .orderByDesc("id")//降序排列
                        .last("limit 0,2");//取出上一次登入的信息
        List<UserLoginRecord> list = userLoginRecordMapper.selectList(wrapper);
        if(list.size() == 1){
            UserLoginRecord userLoginRecord = list.get(0);
            LocalDateTime createTime = userLoginRecord.getCreateTime();

            map.put("createTime",createTime);
        }else {
            UserLoginRecord userLoginRecord = list.get(1);
            LocalDateTime createTime = userLoginRecord.getCreateTime();

            map.put("createTime",createTime);
        }

        //3.查询账户资金信息
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        UserAccount userAccount = userAccountMapper.selectOne(queryWrapper);

        map.put("account",userAccount.getAmount().doubleValue());
        map.put("freezeAmount",userAccount.getFreezeAmount());

        userInfo.setParam(map);
        return userInfo;
    }

    @Override
    public void editHead(String url, String userId) {

        UserInfo userInfo = new UserInfo();
        userInfo.setId(Long.parseLong(userId));
        userInfo.setHeadImg(url);

        baseMapper.updateById(userInfo);
    }
}
